package com.example.proxy;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * <P> Type: Class
 * <P> Description: JDK 动态代理 代理 生成mapper的代理类
 * <P> Date: 2024/6/22:19:19
 */

@SuppressWarnings({"unchecked", ""})
public class MyBatisMapperProxyFactory {
    private static final Logger log = LoggerFactory.getLogger(MyBatisMapperProxyFactory.class);

    private static final SqlSessionFactory factory;

    static {
        SqlSessionFactory factory1;
        try(InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml")) {
            factory1 = new
                    SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        factory = factory1;
    }

    /**
     * 提供工厂方法：用来创建并返回代理类对象
     * 代理对象 完成数据库事务管理
     */
    public static <T> T getMapperProxy(Class<T> obj) {
        ClassLoader classLoader = obj.getClassLoader();
        //传入接口类型
        Class<?>[] interfaces = new Class[]{obj};

        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                SqlSession sqlSession = factory.openSession();
                //获取父类接口，获取 Mapper
                Object mapper = sqlSession.getMapper(obj);

                Object result = method.invoke(mapper, args);

                sqlSession.close();
                return result;
            }
        };

        Object proxy = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);

        return (T) proxy;
    }




}
